package com.rayenterprise.kms.server;

import java.util.List;

import javax.servlet.ServletException;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import net.sf.gilead.core.PersistentBeanManager;
import net.sf.gilead.core.hibernate.HibernateUtil;
import net.sf.gilead.core.store.stateless.StatelessProxyStore;
import net.sf.gilead.gwt.PersistentRemoteService;

import com.rayenterprise.kms.client.remote.NotionRemote;

import com.rayenterprise.kms.domain.FinishedStat;
import com.rayenterprise.kms.domain.KNotion;

public class NotionRemoteService extends PersistentRemoteService implements
		NotionRemote {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void init() throws ServletException {
		super.init();

		// Bean Manager initialization
		//
		HibernateUtil persistenceUtil = new HibernateUtil();
		persistenceUtil.setSessionFactory(HibernateContext.getSessionFactory());

		PersistentBeanManager beanManager = new PersistentBeanManager();
		beanManager.setPersistenceUtil(persistenceUtil);
		beanManager.setProxyStore(new StatelessProxyStore());
		setBeanManager(beanManager);

	}

	@Override
	public List<KNotion> getAll() {
		Session session = null;
		StringBuffer sb = new StringBuffer("");
		sb.append("from KNotion notion order by notion.date");
		try {
			session = HibernateContext.getSessionFactory().openSession();
			Query q = session.createQuery(sb.toString());
			return q.list();
		} catch (RuntimeException e) {

			throw e;
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	/**
	 * Get Notion and subsidiary KInfo objects for the tree 
	 * operation might need KInfo object to be present at 
	 * the object graph
	 * 
	 * @param notionId
	 * @return KNotion
	 * @author h.r.
	 */
	@Override
	public KNotion getNotion(int notionId) {

		Session session = null;
		StringBuffer sb = new StringBuffer("");
		sb.append("from KNotion notion left join fetch notion.infos where notion.notionId =");
		sb.append(notionId);
		try {
			session = HibernateContext.getSessionFactory().openSession();
			Query q = session.createQuery(sb.toString());
			return (KNotion) q.uniqueResult();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	@Override
	public KNotion save(KNotion notion) {
		Session session = null;
		Transaction transaction = null;
		
		try {
			session = HibernateContext.getSessionFactory().openSession();
			transaction = session.getTransaction();
			transaction.begin();
			session.saveOrUpdate(notion);
			transaction.commit();
			return notion;
		} catch (RuntimeException e) {
			transaction.rollback();
			throw e;
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	@Override
	public void deleteNotion(KNotion notion) {
		Session session = null;
		Transaction transaction = null;
		
		try {
			session = HibernateContext.getSessionFactory().openSession();
			transaction = session.getTransaction();
			transaction.begin();
			session.delete(notion);
			transaction.commit();			
		} catch (RuntimeException e) {
			transaction.rollback();
			throw e;
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

	@Override
	public List<FinishedStat> getNotionCompletePercentage() {
		Session session = null;
		StringBuffer sb = new StringBuffer("");
		/*sb.append("select kholder2_.Holder_ID,kholder2_.NAME, count(kinfo0_.Info_ID) as countAll ," +
				" sum(case kinfo0_.is_finished when true then 1 else 0 end) as finishedCount " +
				"		from KInfo kinfo0_, KNotion knotion1_, KHolder kholder2_ " +
				"		where kinfo0_.Notion_ID=knotion1_.Notion_ID and knotion1_.Holder_ID=kholder2_.Holder_ID " +
				"		group by knotion1_.Holder_ID");*/
		sb.append("select new FinishedStat(i.notion.holder.holderId,i.notion.holder.title,count(i)," +
				"sum(case i.isFinished when true then 1.0 else 0 end)) " +
				"from KInfo i group by i.notion.holder");
		
		try {
			session = HibernateContext.getSessionFactory().openSession();
			List<FinishedStat> result = session.createQuery(sb.toString()).list();
			
			return  result;
		} catch (RuntimeException e) {
			throw e;
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

}
